package main

import (
	"errors"
	"fmt"
	"strings"
)

// ==========================================
// 要测试的函数
// ==========================================

// Add 返回两个整数的和
func Add(a, b int) int {
	return a + b
}

// Subtract 返回两个整数的差
func Subtract(a, b int) int {
	return a - b
}

// Multiply 返回两个整数的乘积
func Multiply(a, b int) int {
	return a * b
}

// Divide 返回两个整数的商和可能的错误
func Divide(a, b int) (int, error) {
	if b == 0 {
		return 0, errors.New("除数不能为零")
	}
	return a / b, nil
}

// IsPalindrome 检查字符串是否是回文
func IsPalindrome(s string) bool {
	// 转换为小写并移除非字母数字字符
	s = strings.ToLower(s)
	var result strings.Builder
	for _, r := range s {
		if (r >= 'a' && r <= 'z') || (r >= '0' && r <= '9') {
			result.WriteRune(r)
		}
	}
	s = result.String()

	// 检查是否是回文
	for i := 0; i < len(s)/2; i++ {
		if s[i] != s[len(s)-i-1] {
			return false
		}
	}
	return true
}

// ReverseString 反转字符串
func ReverseString(s string) string {
	runes := []rune(s)
	for i, j := 0, len(runes)-1; i < j; i, j = i+1, j-1 {
		runes[i], runes[j] = runes[j], runes[i]
	}
	return string(runes)
}

// WordCount 统计字符串中的单词数量
func WordCount(s string) map[string]int {
	words := strings.Fields(s)
	counts := make(map[string]int)
	for _, word := range words {
		counts[word]++
	}
	return counts
}

// ==========================================
// 用于演示表格驱动测试的结构体
// ==========================================

// Person3 表示一个人的基本信息
type Person2 struct {
	FirstName string
	LastName  string
	Age       int
}

// FullName 返回人的全名
func (p Person2) FullName() string {
	return p.FirstName + " " + p.LastName
}

// IsAdult 检查人是否成年
func (p Person2) IsAdult() bool {
	return p.Age >= 18
}

func main() {
	// 这个文件主要用于测试，所以main函数很简单
	fmt.Println("Go测试示例")
	fmt.Println("运行 'go test' 来执行测试")

	// 简单演示一些函数
	fmt.Printf("Add(5, 3) = %d\n", Add(5, 3))
	fmt.Printf("IsPalindrome(\"level\") = %t\n", IsPalindrome("level"))
	fmt.Printf("ReverseString(\"Hello\") = %s\n", ReverseString("Hello"))

	// 演示WordCount
	text := "the quick brown fox jumps over the lazy dog"
	counts := WordCount(text)
	fmt.Println("单词统计:")
	for word, count := range counts {
		fmt.Printf("%s: %d\n", word, count)
	}
}

// ==========================================
// 测试相关说明
// ==========================================

/*
Go的测试文件命名规则:
- 测试文件名必须以_test.go结尾
- 测试函数必须以Test开头
- 测试函数接受*testing.T类型的参数

运行测试的命令:
- go test                 # 运行当前包中的所有测试
- go test -v              # 详细输出
- go test -run TestAdd    # 只运行名称匹配的测试
- go test -cover          # 显示测试覆盖率
- go test -coverprofile=c.out  # 生成覆盖率报告
- go tool cover -html=c.out    # 在浏览器中查看覆盖率报告

基准测试:
- 基准测试函数必须以Benchmark开头
- 基准测试函数接受*testing.B类型的参数
- 运行基准测试: go test -bench=.

示例测试:
- 示例函数必须以Example开头
- 示例函数没有参数
- 示例函数的输出通过注释 // Output: 指定
*/
